<?php
# http://projects:8081/cdapp-2kt-api/api/flow_ntfm_load_airports.php

include_once '_portal.php';
// include_once 'flow_ntfm_load_airports_request_contents.php';
include_once 'flow_ntfm_load_airports_nrs.php';

const NTFM_API_URL = 'http://10.202.91.233:2333/NTFM-FORE/forecast/port/queryClassifyFlow';
const MIN_TTL = 1 * 60 * 1000; # unit: ms
const MAX_TTL = 5 * 60 * 1000; # unit: ms
const PARAM_NAME = 'flowAirportsRefreshTime';
const PARAM_NAME_VERSION = 'flowDataAirportsVersion';
const TABLE_NAME = '2kt_flow_record_airports';
const DURATION_HOURS_PASSED = 6;
const DURATION_HOURS_PASSED_DISPOSED = 1;
const DURATION_HOURS = 48;
const STEP_MINUTES = 15;
const HISTORY_LOCK_MOMENT = '04:00:00';
const LOAD_FAKE_RESPONSE = false;

const REQUEST_CONTENTS = [
  'ZUUU' => [
    'item' => 'ZUUU',
    'classContent' => "(adep in ('ZUUU')) and (route_ana like '%;BOKIR;%'):(adep in ('ZUUU')) and (route_ana like '%;GURET;%'):(adep in ('ZUUU')) and (route_ana like '%;UBRAB;%'):(adep in ('ZUUU')) and (route_ana like '%;IDBOR;%'):(adep in ('ZUUU')) and (route_ana like '%;LUVEN;%'):(adep in ('ZUUU')) and (route_ana like '%;MUMGO;%'):(ades in ('ZUUU')) and (route_ana like '%;MEXAD;%'):(ades in ('ZUUU')) and (route_ana like '%;AKDIK;%'):(ades in ('ZUUU')) and (route_ana like '%;EKOKA;%'):(ades in ('ZUUU')) and (route_ana like '%;IGNAK;%'):(ades in ('ZUUU')) and (route_ana like '%;LADUP;%'):other",
    'key' => 'ZUUU_DEP_BOKIR:ZUUU_DEP_GURET:ZUUU_DEP_UBRAB:ZUUU_DEP_IDBOR:ZUUU_DEP_LUVEN:ZUUU_DEP_MUMGO:ZUUU_ARR_MEXAD:ZUUU_ARR_AKDIK:ZUUU_ARR_EKOKA:ZUUU_ARR_IGNAK:ZUUU_ARR_LADUP:ZUUU_OTHER',
  ],
  'ZUTF' => [
    'item' => 'ZUTF',
    'classContent' => "(adep in ('ZUTF')) and (route_ana like '%;BOKIR;%'):(adep in ('ZUTF')) and (route_ana like '%;SAGPI;%'):(adep in ('ZUTF')) and (route_ana like '%;UBRAB;%'):(adep in ('ZUTF')) and (route_ana like '%;ATVAX;%'):(adep in ('ZUTF')) and (route_ana like '%;LUVEN;%'):(adep in ('ZUTF')) and (route_ana like '%;MUMGO;%'):(ades in ('ZUTF')) and (route_ana like '%;MEXAD;%'):(ades in ('ZUTF')) and (route_ana like '%;BUPMI;%'):(ades in ('ZUTF')) and (route_ana like '%;AKOPI;%'):(ades in ('ZUTF')) and (route_ana like '%;ELDUD;%'):(ades in ('ZUTF')) and (route_ana like '%;IGNAK;%'):(ades in ('ZUTF')) and (route_ana like '%;LADUP;%'):other",
    'key' => 'ZUTF_DEP_BOKIR:ZUTF_DEP_SAGPI:ZUTF_DEP_UBRAB:ZUTF_DEP_ATVAX:ZUTF_DEP_LUVEN:ZUTF_DEP_MUMGO:ZUTF_ARR_MEXAD:ZUTF_ARR_BUPMI:ZUTF_ARR_AKOPI:ZUTF_ARR_ELDUD:ZUTF_ARR_IGNAK:ZUTF_ARR_LADUP:ZUTF_OTHER',
  ],
  'ZUMY' => [
    'item' => 'ZUMY',
    'classContent' => "(adep in ('ZUMY')) and (route_ana like '%;BOKIR;%'):(adep in ('ZUMY')) and (route_ana like '%;SAGPI;%'):(adep in ('ZUMY')) and (route_ana like '%;UBRAB;%'):(adep in ('ZUMY')) and (route_ana like '%;JTG;%'):(ades in ('ZUMY')) and (route_ana like '%;MEXAD;%'):(ades in ('ZUMY')) and (route_ana like '%;AKDIK;%'):(ades in ('ZUMY')) and (route_ana like '%;BUPMI;%'):(ades in ('ZUMY')) and (route_ana like '%;IGNAK;%'):(ades in ('ZUMY')) and (route_ana like '%;LADUP;%'):other",
    'key' => 'ZUMY_DEP_BOKIR:ZUMY_DEP_SAGPI:ZUMY_DEP_UBRAB:ZUMY_DEP_JTG:ZUMY_ARR_MEXAD:ZUMY_ARR_AKDIK:ZUMY_ARR_BUPMI:ZUMY_ARR_IGNAK:ZUMY_ARR_LADUP:ZUMY_OTHER',
  ],
];

$force = isset($_GET['force']) ? $_GET['force'] : 0;
$ignore = isset($_GET['ignore']) ? $_GET['ignore'] : 0;

// terminate request SIPDS
if (get_variable('STOP_ALL_NETWORK') === 1) {
  die('Network Stoped');
}
if (get_variable('STOP_NTFM') === 1) {
  die('NTFM Stoped');
}

output(main($force, $ignore));

die();

function main($force = 0, $ignore = 0) {
  # refresh information
  $refresh_info = get_param(PARAM_NAME);
  if (!$refresh_info) {
    $refresh_info = ['tx' => 1000, 'rx' => 2000];
  }
  $ttl_verify = verify_ttl($refresh_info['tx'], $refresh_info['rx'], MIN_TTL, MAX_TTL);
  $info = 'flow_ntfm_load: ' . $ttl_verify['info'];
  $status = $ttl_verify['status'];
  # need for refresh
  if ($status > 0 || $force > 0) {
    $time_tx = timestamp();
    $time_rx = $refresh_info['rx'];
    save_param(PARAM_NAME, ['tx' => $time_tx, 'rx' => $time_rx]);
    // goting to request
    $result = ['countCell' => 0, 'requestStatus' => true, 'fetchStatus' => true, 'details' => []];
    foreach (REQUEST_CONTENTS as $content) {
      $payload = [
        "begTime" => "",
        "class" => "DIY",
        "classContent" => "",
        "endTime" => "",
        "filter" => "",
        "histUnEffect" => "Y",
        "item" => "",
        "key" => ":",
        "region" => "ZU_REGION",
        "step" => "",
        "waitPool" => "N",
      ];
      $payload['item'] = $content['item'];
      $payload['classContent'] = $content['classContent'];
      $payload['key'] = $content['key'];
      $response_full = request_ntfm($payload);
      $response = $response_full['response'];
      $result_detail = fetch_response($response, $ignore);
      // $result_detail['item'] = $response_full['info']['item'];
      // $result_detail['payload'] = $response_full['payload'];
      // $result_detail['response'] = $response_full['response'];
      $result['details'][] = $result_detail;
      $result['countCell'] += $result_detail['countCell'];
      $result['requestStatus'] = $result['requestStatus'] && $result_detail['requestStatus'];
      $result['requestStatus'] = $result['fetchStatus'] && $result_detail['fetchStatus'];
    }
    // finished request
    $result_ext = update_details();
    $result_his = update_history();
    $successed = $result['countCell'] > 0 && $result['requestStatus'] && $result['fetchStatus'];
    if ($successed) {
      save_param(PARAM_NAME, ['tx' => $time_tx, 'rx' => $time_rx]);
      save_param(PARAM_NAME_VERSION, ['value' => date('Y-m-d H:i:s')]);
    }
    $time_rx = timestamp();
    $duration = $time_rx - $time_tx;
    return [
      'message' => 'Load NTFM airports data: ' . ($force > 0 ? 'Forced refresh manually' : $info),
      'successed' => $successed,
      'modifiers' => ['force' => $force, 'ignore' => $ignore],
      'duration' => $duration,
      'cellCount' => $result['countCell'],
      'historyUpdate' => $result_his,
      'normalRate' => $result_ext,
      // 'result' => $result,
      // 'response' => $response,
      // 'fullResponse' => $response_full,
    ];
  } else {
    return [
      'message' => 'Load NTFM airports data: ' . $info,
      'successed' => false,
      'duration' => 0,
      'result' => null,
      // 'response' => null,
      // 'fullResponse' => null,
    ];
  }
}

function fetch_response($response, $ignore = 0) {
  if (!$response || $response == null || !isset($response)) {
    // $result_ext = update_details();
    # 无 NTFM_response 的情况
    return [
      'requestDuration' => 0,
      'requestStatus' => false,
      'fetchDuration' => 0,
      'fetchStatus' => false,
      // 'detailsStatus' => $result_ext,
       'countCell' => 0,
      'countLine' => 0,
      'rawData' => [],
    ];
  }
  $all_zero = true;
  $timestamp = timestamp();
  $item = $response['info']['item'];
  $step = $response['info']['step'];
  $begTime = $response['info']['begTime'];
  $endTime = $response['info']['endTime'];
  $count = floor((strtotime($endTime) - strtotime($begTime)) / ($step * 60)) + 1;
  $keys = explode(':', $response['info']['payload']['key']);
  $data = $response['data'];
  $table_name = TABLE_NAME;
  $sql = "INSERT INTO `{$table_name}`(`moment`, `item`, `content`, `history`, `mixKey`) VALUES ";
  $output = [];
  $dataCount = 0;
  # dispose first several cells due to bugs of NTFM
  $startIndex = DURATION_HOURS_PASSED_DISPOSED * round(60 / STEP_MINUTES); // STEP_MINUTES or $step
  for ($i = $startIndex; $i < $count; $i++) {
    $stamp = strtotime($begTime) + $i * $step * 60;
    $moment = date('Y-m-d H:i:s', $stamp);
    $content = [];
    foreach ($keys as $label) {
      $value = $data['arr'][$label][$i] + $data['dep'][$label][$i];
      // $content[] = ($label == 'other' && $ignore) ? 0 : $value;
      $content[] = $value;
      $dataCount++;
      $all_zero = $all_zero && ($value == 0 || $value == '0' || $value == null);
    }
    $output[] = ['moment' => $moment, 'content' => $content];
    $content_json = json_stringify($content);
    $mix_key = "{$stamp}.{$item}";
    $sql .= "('{$moment}','{$item}','{$content_json}','{$content_json}','{$mix_key}'),";
  }
  if ($all_zero) {
    // $result_ext = update_details();
    # NTFM_response 全0的情况
    return [
      // 'tags' => $tags,
       'requestDuration' => $response['info']['duration'],
      'requestStatus' => false,
      'fetchDuration' => timestamp() - $timestamp,
      'fetchStatus' => false,
      // 'detailsStatus' => $result_ext,
       'countCell' => $dataCount,
      'countLine' => $count,
      'rawData' => $output,
      // 'sql' => $sql,
    ];
  } else {
    $sql = rtrim($sql, ',');
    $updated = date('Y-m-d H:i:s');
    $sql .= " ON DUPLICATE KEY UPDATE `content` = VALUES(`content`),`updated` = '{$updated}'";
    $result = exec_sql($sql);
    # NTFM_response 正常的情况
    return [
      // 'tags' => $tags,
       'requestDuration' => $response['info']['duration'],
      'requestStatus' => true,
      'fetchDuration' => timestamp() - $timestamp,
      'fetchStatus' => $result,
      // 'detailsStatus' => $result_ext,
       // 'historyStatus' => $result_his,
       'countCell' => $dataCount,
      'countLine' => $count,
      'rawData' => $output,
      // 'sql' => $sql,
    ];
  }
}

function request_ntfm($payload = null) {
  if (!$payload) {
    return null;
  }
  $timestamp = timestamp();
  // $payload = json_parse(file_get_contents(REQUEST_CONTENT_EXAMPLE_FILE_PATH));
  $info = [];
  $info['item'] = $payload['item'];
  $info['step'] = $payload['step'] = STEP_MINUTES;
  $info['begTime'] = $payload['begTime'] = date('Y-m-d H', time() - 3600 * DURATION_HOURS_PASSED) . ':00:00';
  $info['endTime'] = $payload['endTime'] = date('Y-m-d H', time() + 3600 * DURATION_HOURS) . ':00:00';
  $info['tags'] = explode(':', $payload['key']);
  $info['payload'] = $payload;
  $response_raw = null;
  $response = null;
  if (LOAD_FAKE_RESPONSE) {
    $response = file_get_contents(REQUEST_RESPONSE_EXAMPLE_FILE_PATH);
  } else {
    $curl = curl_init();
    curl_setopt_array($curl, array(
      CURLOPT_URL => NTFM_API_URL,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => '',
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 60,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => 'POST',
      CURLOPT_POSTFIELDS => json_stringify($payload),
      CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
      ),
    ));
    $response_raw = $response = curl_exec($curl);
    curl_close($curl);
    // echo $response;
  }
  if ($response != null && $response != '' && $response) {
    $res_object = json_parse($response);
    if (gettype($res_object) != 'array') {return null;}
    $info['duration'] = timestamp() - $timestamp;
    $res_object['info'] = $info;
    $res_object['status'] = true;
    return [
      'response' => $res_object,
      'info' => $info,
      'payload' => $payload,
      'raw' => $response_raw,
    ];
  } else {
    return [
      'response' => null,
      'info' => $info,
      'payload' => $payload,
      'raw' => $response_raw,
    ];
  }
}

function update_history() {
  $table_name = TABLE_NAME;
  # Update history data
  // obsolete computing for history threshold
  // $history_threshold = date('Y-m-d H:i:s', time() + HISTORY_LOCK_HOURS + 3600);
  # 每日0400前更新当日0400含以后的计划架次，0400后更新次日计划架次
  $history_threshold = date('Y-m-d') . ' ' . HISTORY_LOCK_MOMENT;
  if (time() > strtotime($history_threshold)) {
    $history_threshold = date('Y-m-d', strtotime("tomorrow")) . ' ' . HISTORY_LOCK_MOMENT;
  }
  $sql_his = "UPDATE `{$table_name}` SET `history`=`content` WHERE `moment` >= '{$history_threshold}'";
  $result_his = exec_sql($sql_his);
  return $result_his;
}
function update_details() {
  $table_name = TABLE_NAME;
  $nrs = load_nrs();
  $sqls = [];
  $result = true;
  $content = [];

  if (!is_null($nrs)) {
    $current = date('Y-m-d H:i:s');
    $minute = (int)date('i');
    $minute_piece = $minute < 15 ? '00' : ($minute < 30 ? '15' : ($minute < 45 ? '30' : '45'));
    $hour = (int)date('H');
    $from = date('Y-m-d H:') . $minute_piece . ':00';
    $to = date('Y-m-d ') . ($hour < 23 ? ($hour + 1) : '00') . ':00:00';
    foreach ($nrs as $details) {
      $details['update'] = $current;
      $airport = $details['airport'];
      $dnr_tkf = $details['dnr_tkf'];
      $hnr_tkf = $details['hnr_tkf'];
      $details_json = json_stringify($details);
      $sql = "UPDATE `{$table_name}` SET `dayTNR`={$dnr_tkf},`hourTNR`={$hnr_tkf},`details`='{$details_json}' WHERE `moment`>='{$from}' AND `moment`<='{$to}' AND `item`='{$airport}'";
      $sqls[] = $sql;
      $result = $result && exec_sql($sql);
      $content[] = $details;
    }
    // $result = exec_sql_array($sqls);
  }
  return [
    'result' => $result,
    '$sql' => $sqls,
    'content' => $content,
  ];
}
